Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add excludedRunes option to the prefer-const rule #1064

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

baseballyama
Copy link
Member

close part of #818

As explained here, $state also needs to be excluded from the prefer-const rule.
#985 (comment)

Copy link

changeset-bot bot commented Feb 9, 2025

🦋 Changeset detected

Latest commit: e4f255e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
eslint-plugin-svelte Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor

github-actions bot commented Feb 9, 2025

Try the Instant Preview in Online Playground

ESLint Online Playground

Install the Instant Preview to Your Local

npm i https://pkg.pr.new/eslint-plugin-svelte@1064

Published Instant Preview Packages:

View Commit

@ota-meshi
Copy link
Member

I still don't understand why you want to ignore $state from svelte/prefer-const rule.

I know that some users want to use let to change value with const value = $state({ value: new Date().toString() });, but I think that user would do the same with const value = { value: new Date().toString() }; which doesn't use $state(). In other words, I think that user would always turn off the prefer-const rule.
So I don't think there's a need to ignore $state from the svelte/prefer-const rule check.

@baseballyama
Copy link
Member Author

We might want to enable prefer-const for plain JavaScript that has nothing to do with Svelte.

In other words, semantically, since $state is something that can be reassigned, we may want to consistently use let for it. However, it’s understandable that some users would prefer to use prefer-const for regular JavaScript outside of that.

(Personally, I always use const consistently, though.😅)

@baseballyama
Copy link
Member Author

In this case, there is no actual reassignment, so prefer-const would allow it to be declared as const. However, semantically, some people may prefer to declare it with let.

export const Time3 = () => {
	// If `$state` has object value,
	// Time3 user cn reassign `value.value` even without reassign logic in this composable.
	// Therefore it can be declare as both `const` / `let`
	const value = $state( { value: new Date().toString() });

	return {
		get value() {
			return value;
		}
	}
}

@ota-meshi
Copy link
Member

I understand that when a user uses $state(), it is clear that the user intends a variable that will be mutated. However, objects that do not use $state() may also be mutable, so for consistency, I think that users who prefer let should also use let for them.
In other words, the prefer-const issue with mutable objects is not a problem specific to $state() (Svelte syntax), so I don't think it should be specially ignored.

@baseballyama
Copy link
Member Author

Therefore, I am considering creating a separate rule, prefer-let. This rule will enforce the consistent use of let.

@baseballyama
Copy link
Member Author

@ota-meshi So, what you’re saying is that extending prefer-const in the first place is unnecessary?

@ota-meshi
Copy link
Member

ota-meshi commented Feb 9, 2025

So, what you’re saying is that extending prefer-const in the first place is unnecessary?

No, I think svelte/prefer-const is necessary.
I don't think there's any need to ignore $state() from the svelte/prefer-const rule check.

Since we don't ignore svelte/prefer-const rule checks for mutable objects regardless of $state(), I think the rule would be inconsistent if we were to ignore only $state() from svelte/prefer-const rule checks.

If a primitive value of $state() is reported with prefer-const, it's just a case of the user using it incorrectly, and I think we can follow it with a different rule (e.g. prefer-let).

@baseballyama
Copy link
Member Author

If a primitive value of $state() is reported with prefer-const, it's just a case of the user using it incorrectly, and I think we can follow it with a different rule (e.g. prefer-let).

I still don’t fully understand this part. Since $state can hold non-primitive values such as object, are there cases where there is no direct reassignment? In such cases, is it correct for const to be enforced? Even if a prefer-let rule were implemented, wouldn’t it conflict with prefer-const, which enforces const?

https://svelte.dev/playground/hello-world?version=5.19.9#H4sIAAAAAAAAE32MzQqDMBAGX2VZCiqIlh6DFXrrO9Qeom4lkMaQrLZFfPcSpT-H0tsy38xOaOSVUOCRtO7h1jvdQkytYmoTTPGiNHkUpwn5YYMXAKav6mBt5kfSHFgtPf3iTW-YDHsUWPjGKctlZSrWxDB4crCHjWfJFMMEoRcQSa0ailKQHQnYbWGGpDJF_qlNYcvVncKPLNxzkdtyWZZsHWT35srYgaFWphWj1APtv1LI_xjhxyJgikx3RsFuoPk8PwFxCBbbPgEAAA==

@ota-meshi
Copy link
Member

The area I have an issue with is the consistency of the rule.

@baseballyama
Copy link
Member Author

I fully understand your perspective.👍

As stated in the documentation, Svelte runes recommend using let. Based on my understanding, some users interpret JavaScript rules as being overridden by Svelte rules.
https://svelte.dev/docs/svelte/$state

In your example, since user does not use runes, I understood that standard JavaScript rules apply (without being overridden by Svelte rules). Therefore, I believed that the behavior of this PR was consistent.

Additionally, based on your reasoning, shouldn’t $props and $derived also consistently use const whenever possible? (I may not yet fully understand this part.)

@ota-meshi
Copy link
Member

I think the reason why $derived should be let is because it is changed from outside.
But $state doesn't really fit that reason.
For primitive values, the user should assign it somewhere, so it won't be reported to prefer-const.
If the reason to use let is that the object is mutable, then I think objects with setters should use let.

Svelte runes recommend using let.

Hmm... I don't think it explicitly says "recommended". I think it's still a matter of user preference 🤔

@baseballyama
Copy link
Member Author

I see. Would adding a config be a good middle ground? Like { enforceState: false }?
I want to accommodate users who wish to use prefer-const in some way but also want to consistently use let for runes.

@ota-meshi
Copy link
Member

I want to accommodate users who wish to use prefer-const in some way but also want to consistently use let for runes.

If there are users requesting it, I think it makes sense to add the option.

@baseballyama
Copy link
Member Author

Got it. In that case, since there are no breaking changes, I will try implementing this option after the v3 release.

@baseballyama baseballyama marked this pull request as draft February 9, 2025 14:12
@baseballyama baseballyama changed the title fix: ignore $state in the prefer-const rule feat: add excludedRunes option to the prefer-const rule Feb 23, 2025
@baseballyama baseballyama marked this pull request as ready for review February 23, 2025 13:44
@baseballyama
Copy link
Member Author

I added excludedRunes option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants